#include "widget.h"
#include "ui_widget.h"
#include <QDesktopWidget>
#include <QDebug>
#include <math.h>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    //主窗口配置
    this->setWindowIcon(QIcon(":/pic/seri.png"));
    this->setWindowTitle(tr("龙芯示波器"));

    //串口配置
    this->system_init();  //系统各组件初始化

    //    //自动识别输出窗口大小
    //    QDesktopWidget *deskTopWidget =QApplication::desktop();
    //    QRect deskRect = deskTopWidget->availableGeometry();
    //    int appH = deskRect.height();
    //    int appW = deskRect.width();
    //    setGeometry(0,0,appW,appH);



}

Widget::~Widget()
{
    delete ui;
}

void Widget::system_init()
{
    //设置串口端口
    QStringList m_serialPortName;
    m_serialPortName = getPortNameList();  //获取串口信息
    qDebug()<<m_serialPortName;
    ui->portID->clear();
    ui->portID->addItems(m_serialPortName);
    if(m_serialPortName.size()>=2){
        ui->portID->setCurrentIndex(1);//串口个数>=2,默认选第二个串口
    }

    // 串口初始化配置
    global_port.setBaudRate(115200, QSerialPort::AllDirections); //配置波特率
    global_port.setParity(QSerialPort::NoParity);  //无奇偶校验位
    global_port.setDataBits(QSerialPort::Data8);   //8位校验位
    global_port.setStopBits(QSerialPort::OneStop); //停止位为1
    global_port.setFlowControl(QSerialPort::NoFlowControl);   //无流控制
    connect(&global_port, SIGNAL(readyRead()), this, SLOT(receiveInfo()));


    /**********************************************************************/


    /*--------------------------------
     *  构造示波器
     *-------------------------------*/
    ui->customPlot->setBackground(QBrush(QColor("#474848")));
    ui->customPlot->axisRect()->setupFullAxesBox();
    ui->customPlot->yAxis->setRange(-4, 4);
    ui->customPlot->xAxis->setRange(0,200);

    //创建曲线
    creat_graph();

    //第一次禁止AUTO键
    ui->auto_btn->setEnabled(false);

}

QStringList Widget::getPortNameList()
{
    /*--------------------------------
     *  获取系统串口信息
     *-------------------------------*/
    QStringList m_serialPortName;
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        m_serialPortName << info.portName();
        qDebug()<<"serialPortName:"<<info.portName();
    }
    return m_serialPortName;
}

void Widget::creat_graph()
{
    ui->customPlot->addGraph();

    //示波器曲线的样式
    QPen pen;
    pen.setColor(Qt::yellow);
    pen.setWidth(3);
    ui->customPlot->graph(0)->setPen(pen);
    ui->customPlot->graph()->setAntialiased(true);//打开抗锯齿
}

void Widget::creat_sin_osc()
{
    //正弦曲线公式 y = A * sin(ωx + φ) + k
    double w = M_PI/10;  //w为角速度 ，可以理解为波浪的密度，越大密度越大
    double A = 2;    //  A表示振幅,可以理解为水波的高度,越大高度越高
    double k = 0;    //  k表示y轴偏移
    double m_offset = 0; //初相位，初值该值不一样，获得waveY也不一样，可试验该值为不同值的时候，曲线的起始点的区别        //
    for(int x = 0; x < 1000; x+=1)  //x从0~w的值而改变，从而得到正弦曲线
    {

        double waveY = (double)(A * sin(w * x + m_offset)) + k;// waveY随着x的值改变而改变，从而得到正弦曲线
        x_val.append(x);
        y_val.append(waveY);
        //        x_val.push_back(x);
        //        y_val.push_front(waveY);

    }

    ui->customPlot->graph(0)->setData(x_val,y_val);//将数据添加到图表上
    ui->customPlot->replot();//重新绘制图形

}

Widget::Typedef_osc Widget::findExtremum(const QVector<double> &floatArray)
{
    Typedef_osc result;
    result.min_value=result.max_value = floatArray.isEmpty() ? 0 : floatArray.at(0);
    result.min_index=result.max_index = 0;

    /**冒泡排序，要快的话使用快速排序**/
    for (int i = 1; i < floatArray.size(); ++i) {
        if (floatArray.at(i) > result.max_value) {
            result.max_value = floatArray.at(i);
            result.max_index = i;
        }

        if (floatArray.at(i) < result.min_value) {
            result.min_value = floatArray.at(i);
            result.min_index = i;
        }
    }
    Vpp=result.max_value-result.min_value;

    return result;
}

Widget::Typedef_osc Widget::quickSort(QVector<double> &arr, int left, int right)
{
    Typedef_osc result;
    int i = left, j = right;
    double pivot = arr[(left + right) / 2];

    while (i <= j) {
        while (arr[i] < pivot) {
            i++;
        }
        while (arr[j] > pivot) {
            j--;
        }
        if (i <= j) {
            std::swap(arr[i], arr[j]);
            i++;
            j--;
        }
    }

    if (left < j) {
        quickSort(arr, left, j);
    }
    if (i < right) {
        quickSort(arr, i, right);
    }
    result.max_value=arr.back();
    result.min_value=arr.front();
    Vpp=1.14*(result.max_value-result.min_value)-0.05;
    qDebug()<<result.max_value<<"max";
    qDebug()<<result.min_value<<"min";
    return result;
}


void Widget::receiveInfo()
{
    /*--------------------------------
     *  接受串口信息
     *-------------------------------*/
    QByteArray data,buffer,freqData;
    float V_data;
    int info;
    if(freq_flag){
        data=global_port.read(1);
        info=data.toHex().toInt(0,16);
        //    int info=data.toInt(0,16);//16进制接收数据,再16进制转为10进制
        V_data=(info*3.3/230);//电压值
        float Ac_data=V_data-(1.2/2*max_val);

        x_val.append(count);
        y_val.append(Ac_data);
        v_val.append(V_data);
        count+=1;

        if(count>=512){
            count=0;
            count_y=y_val.mid(100,450);
            count_x=x_val;
            v_val=v_val.mid(100,450);
            osc_data=quickSort(v_val,0,v_val.size()-1);
            max_val=osc_data.max_value;
            ui->vpp_lable->setText(QString::number(Vpp,'f',2)+"V");
            ui->customPlot->graph(0)->setData(count_x,count_y);//将数据添加到图表上
            ui->customPlot->replot();
            x_val.clear();
            y_val.clear();
            v_val.clear();
            memset(&osc_data, 0, sizeof(Typedef_osc));
            freq_flag=false;
        }
    }
    else
    {
        global_port.write("F", 1);
        freqData=global_port.readAll();
        for (int i = 0; i < freqData.size(); ++i) {
            if (!receivingData) {
                if (static_cast<unsigned char>(freqData[i]) == 0x85&&static_cast<unsigned char>(freqData[i+5]) == 0x85) { // 0x85 对应 85
                    receivingData = true;
                    buffer.clear();
                }
            } else {
                buffer.append(freqData[i]);
                if (buffer.size() >= 4) {

                    freq=buffer.toHex().toInt(0,16);
                    receivingData = false; // 重置状态
                    ui->freq_label->setText(QString::number(freq)+"Hz");
                    freq_flag=true;
                    return;
                }
            }
        }


    }

//    qDebug()<<freqData.toHex();
//    qDebug()<<freq;
//    qDebug()<<buffer.toHex();
//        qDebug()<<info<<"max";
//        qDebug()<<Vpp<<"Vpp";
//        qDebug()<<osc_data.min_value<<"min";
}


void Widget::on_open_btn_clicked()
{
    /*--------------------------------
     *  打开或者关闭串口
     *-------------------------------*/
    if (!this->OpenorClose_Flag){

        // 打开串口
        ui->open_btn->setText("暂停");
        this->OpenorClose_Flag = true;


        /**将拖动后的图形恢复到合适的位置*/
        ui->customPlot->setInteractions(0);//禁止可拖拽+可滚轮缩放
        ui->customPlot->yAxis->setRange(-4, 4);
        ui->customPlot->xAxis->setRange(0,200);
        ui->customPlot->replot();//重新绘制图形

        //Serial 配置
        QString portId;
        portId = ui->portID->currentText();
        qDebug() << "portId: " << portId;
        global_port.setPortName(portId);  //配置端口号



        // 配置完成,开启串口
        global_port.open(QIODevice::ReadWrite);
        ui->auto_btn->setEnabled(true);
        qDebug() << "Open Serial Successfully";
    }else{
        // 关闭串口
        global_port.close();
        ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);      //可拖拽+可滚轮缩放
        qDebug() << "Close Serial Successfully";
        ui->open_btn->setText("显示");
        this->OpenorClose_Flag = false;
    }
}

void Widget::on_hv_btn_clicked()
{
    if (stop_flag){
        ui->customPlot->axisRect()->setRangeZoom(Qt::Vertical);
        stop_flag = false;
        ui->hv_btn->setText("水平");
    }else{
        ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal);
        stop_flag = true;
        ui->hv_btn->setText("垂直");
    }
}

void Widget::on_single_btn_clicked()
{
    //    ui->customPlot->rescaleAxes();//调整合适窗口
    //    ui->customPlot->clearGraphs();
    //    creat_graph();
}

void Widget::on_save_btn_clicked()
{
    save_x=count_x;
    save_y=count_y;
    save_freq=freq;
    save_Vpp=Vpp;
}

void Widget::on_show_btn_clicked()
{
    this->OpenorClose_Flag = false;
    // 关闭串口
    global_port.close();
    ui->open_btn->setText("显示");
    x_val=save_x;
    y_val=save_y;
    ui->customPlot->graph(0)->setData(x_val,y_val);//将数据添加到图表上
    ui->customPlot->replot();
    ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);      //可拖拽+可滚轮缩放
    ui->freq_label->setText(QString::number(save_freq)+"Hz");
    ui->vpp_lable->setText(QString::number(save_Vpp,'f',2)+"V");
}

void Widget::on_auto_btn_clicked()
{

    // 打开串口
    ui->open_btn->setText("暂停");
    this->OpenorClose_Flag = true;
    // 配置完成,开启串口
    global_port.open(QIODevice::ReadWrite);
    /**将拖动后的图形恢复到合适的位置*/
    ui->customPlot->setInteractions(0);//禁止可拖拽+可滚轮缩放
    ui->customPlot->yAxis->setRange(-4, 4);
    ui->customPlot->xAxis->setRange(0,200);
    ui->customPlot->replot();//重新绘制图形
    global_port.write("A", 1);
}

void Widget::on_syns_btn_clicked()
{

}
